package com.huatai.exchange.deal;

import com.faneui.common.exception.BusinessException;
import com.faneui.common.utils.Constants;
import com.faneui.common.utils.ListUtils;
import com.faneui.dal.DBUtils;
import com.faneui.dbf.utils.DBFUtils;
import com.faneui.dbf.yss.DBFReader;
import com.faneui.dbf.yss.JDBField;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.huatai.exchange.dal.model.ExcDataFileInfo;
import com.huatai.exchange.facade.Contents;
import com.huatai.exchange.facade.FileSourceConstants;
import com.huatai.exchange.utils.FileDealUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service("fileCreateSqlDealService")
public class FileCreateSqlDealServiceImpl extends AbstractFileCreateDealServiceImpl implements FileCreateDealService {

    private static Map<String, Object[]> templateFileFieldCache = Maps.newConcurrentMap();

    @Override
    void generate(Map<String, Object> valueMap, ExcDataFileInfo dataFileInfo, StringBuffer fileNames, StringBuffer filePaths) throws BusinessException {
//        logger.info("参数："+ JSON.toJSONString(valueMap));
        String tmpFilePath = tmpFile + UUID.randomUUID().toString();
        String templateFilePath = null;
        try {
            String fileTemplatePath = dataFileInfo.getTemplateFilePath() ;
//            String fileTemplate = (String) valueMap.get(FileSourceConstants.FILE_TEMPLATE);
            Connection conn = getConn(valueMap);
            String tmpSql = formatStr((String) valueMap.get(FileSourceConstants.SQL_CONTENT), valueMap);
            //

            String filePath = fileTemplatePath;
            List<Map<String, Object>> result = DBUtils.executeQuery(conn, tmpSql);
            if (ListUtils.isNotEmpty(result)) {
                String isChinese = (String) valueMap.get(FileSourceConstants.FILE_HAS_CHINESE_FIELD);
                Object[] objects = getDBFFields(valueMap,dataFileInfo.getId(),fileTemplatePath) ;
                String field = (String) valueMap.get(FileSourceConstants.MOREFILE_PARAM);
                if(StringUtils.isBlank(field)) {
                    FileDealUtils.createDBFFile(isChinese, tmpFilePath, filePath, objects, result);
                    File tmpFile = new File(tmpFilePath);
                    filePath = fileOperateService.uploadFile(tmpFile);
                    String fileName = formatStr(dataFileInfo.getFileName(), valueMap);
                    fileNames.append(",").append(fileName);
                    filePaths.append(",").append(filePath);
                    valueMap.put(Contents.FILE_GC, valueMap.get(Contents.FILE_GC) + "," + filePath);
                } else {
                    Map<String, List<Map<String, Object>>>  dataListMap = splitData(result,field) ;
                    for(String key:dataListMap.keySet()){
                        Map<String,Object> map = Maps.newHashMap() ;
                        map.put(field,key) ;
                        map.putAll(valueMap);
                        FileDealUtils.createDBFFile(isChinese, tmpFilePath, filePath, objects, dataListMap.get(key));
                        File tmpFile = new File(tmpFilePath);
                        filePath = fileOperateService.uploadFile(tmpFile);
                        String fileName = formatStr(dataFileInfo.getFileName(), map);
                        fileNames.append(",").append(fileName);
                        filePaths.append(",").append(filePath);
                        valueMap.put(Contents.FILE_GC, valueMap.get(Contents.FILE_GC) + "," + filePath);
                    }
                }

            } else {
                String isNullable = (String) valueMap.get(FileSourceConstants.FILE_IS_NULL_ABLE) ;

                if(StringUtils.isBlank(isNullable) || "1".equalsIgnoreCase(isNullable)) {
                    String fileName = formatStr(dataFileInfo.getFileName(), valueMap);
                    fileNames.append(",").append(fileName);
                    filePaths.append(",").append(filePath);
                }
            }
        } catch (Exception ex) {
            BusinessException.throwBusinessException(ex);
        } finally {
            new File(tmpFilePath).deleteOnExit();
            if(StringUtils.isNotBlank(templateFilePath))
                new File(templateFilePath).deleteOnExit();
        }
    }


    private Object[] getDBFFields(Map<String, Object> valueMap, String fileInfoId, String templateFilePath) throws BusinessException {
        Object[] objects = templateFileFieldCache.get(fileInfoId);

        String isChinese = (String) valueMap.get(FileSourceConstants.FILE_HAS_CHINESE_FIELD);
        if (objects == null) {
            // 判断是否是中文列，因为中文列获取列值时是乱码 ，所以提前设置好 中文参数
            if (Constants.boolean_true.equals(isChinese)) {
                logger.info("中文列处理开始 ");
                try {
                    DBFReader reader = new DBFReader(templateFilePath);
                    List<JDBField> jdbFields = Lists.newArrayList();
                    for (int i = 0; i < reader.getFieldCount(); i++) {
                        jdbFields.add(reader.getField(i));
                    }
                    objects = jdbFields.toArray();
                    logger.info("列数： " + objects.length);
                    logger.info("类" + objects[0].getClass());
                    templateFileFieldCache.put(fileInfoId, objects);
                } catch (Exception ex) {
                    BusinessException.throwBusinessException(ex);
                }
            } else {
                objects = DBFUtils.getDBFields(templateFilePath);
                logger.info("列数： " + objects.length);
                logger.info("类" + objects[0].getClass());
                templateFileFieldCache.put(fileInfoId, objects);
            }
        }
        return objects;
    }

    private Map<String, List<Map<String, Object>>> splitData( List<Map<String, Object>> result,String field) {
        Map<String, List<Map<String, Object>>> dataListMap = Maps.newHashMap();
        for (Map<String, Object> map : result) {
            String value = (String) map.get(field.toUpperCase());
            List<Map<String, Object>> dataList = dataListMap.computeIfAbsent(value, k -> Lists.newArrayList());
            dataList.add(map);
        }
        return dataListMap;
    }
}
